﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Threading;

namespace Sustainalytics.Utils.Logging
{
    public interface ILogWriter
    {
        void WriteMessage(string msg, EventLevel level);
    }

    public class ConsoleLogWriter : ILogWriter
    {
        public void WriteMessage(string msg, EventLevel level)
        {
            Console.WriteLine(msg);
        }
    }

    public class DebugLogWriter : ILogWriter
    {
        public void WriteMessage(string msg, EventLevel level)
        {
            Debug.WriteLine(msg);
        }
    }

    public class LogAggreator
    {
        public const string CLUSTER_SERV_LOG = "Cluster.Serv.Log";

        private readonly Dictionary<string, List<ILogWriter>> _dictWriter;

        private static readonly Lazy<LogAggreator> LazyLog = new Lazy<LogAggreator>(() => new LogAggreator(),
            LazyThreadSafetyMode.ExecutionAndPublication);

        private LogAggreator()
        {
            _dictWriter = new Dictionary<string, List<ILogWriter>>();
        }

        public static LogAggreator GetIntstance()
        {
            return LazyLog.Value;
        }

        public void AddSourceLog(string source, List<ILogWriter> writert)
        {
            if (_dictWriter.ContainsKey(source))
            {
                var data = _dictWriter[source];
                if (data == null) data = new List<ILogWriter>();
                data.Clear();
                data.AddRange(writert);
                return;
            }
            _dictWriter.Add(source, writert);
        }

        public void RemoveSourceLog(string source)
        {
            if (!_dictWriter.ContainsKey(source)) return;
            _dictWriter.Remove(source);
        }

        public void NotifyLogSubscribers(string source, string msg, EventLevel level)
        {
            if (!_dictWriter.ContainsKey(source)) throw new ArgumentException(String.Format("The current data log source {0} was not found", source));
            var data = _dictWriter[source];
            foreach (var logWriter in data)
            {
                if (logWriter == null) continue;

                logWriter.WriteMessage($"{DateTime.Now.ToString("G")} - {source} {level} : {msg}", level);
            }
        }

        public static void WriteLog(string source, string msg, EventLevel level)
        {
            var instance = GetIntstance();
            instance.NotifyLogSubscribers(source, msg, level);
        }
    }
}
